package personal.lijun.skeleton.springcloud.gateway.config;

import com.google.code.kaptcha.Constants;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import personal.lijun.skeleton.springcloud.gateway.context.ReactiveExchangeContextHolder;
import reactor.core.publisher.Mono;

@Component
public class SecurityUserDetailsService implements ReactiveUserDetailsService {

    @Value("${spring.security.user.name}")
    private String userName;

    @Value("${spring.security.user.password}")
    private String password;


    @Override
    public Mono<UserDetails> findByUsername(String username) {
        //todo 预留调用数据库根据用户名获取用户
        if (StringUtils.equals(userName, username)) {
            return ReactiveExchangeContextHolder.getExchange().flatMap(exchange -> {
                        Mono<String> captcha = exchange.getFormData().flatMap(map ->{
                            String req_captcha = map.getFirst("captcha");
                            if(StringUtils.isEmpty(req_captcha))
                                return Mono.error(new BadCredentialsException("验证码错误,未从请求中获取验证码"));
                            else
                               return Mono.just((String) map.getFirst("captcha"));
                        });
                        return exchange.getSession().flatMap(session -> captcha.flatMap(item -> {
                            String session_captcha = session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
                            if (session_captcha == null) {
                                return Mono.error(new BadCredentialsException("验证码错误,验证码已过期"));
                            } else if (!session_captcha.equals(item)) {
                                return Mono.error(new BadCredentialsException("验证码错误"));
                            } else {
                                UserDetails user = User.withUsername(userName)
                                        .password(encodePswd(password))
                                        .roles("admin").authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("admin"))
                                        .build();
                                return Mono.just(user);
                            }
                        }));
                    }
            );

        } else {
            return Mono.error(new UsernameNotFoundException("User Not Found"));

        }

    }

    private String encodePswd(String password) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(4);
        String encodedPassword = encoder.encode(password);
        return encodedPassword;
    }
}
